package multilock;

import java.util.Date;

/**
 * Created by sunyuming on 19/8/28.
 */
public class MultiLock {

    public Integer lockInteger;
    public String lockString;
    public String lockStringNew;

    public static void main(String [] f) throws InterruptedException {
        MultiLock a = new MultiLock();
        MultiLock b = new MultiLock();
        a.lockInteger = 127;
        b.lockInteger = 127;
        a.lockString = "abc";
        b.lockString = "abc";
        a.lockStringNew = new String("abc");
        b.lockStringNew = new String("abc");

        System.out.println("\n当127自动装箱Integer时");
        new Thread(new MyThreadInteger(a)).start();
        new Thread(new MyThreadInteger(b)).start();

        Thread.sleep(10000);
        a.lockInteger = 128;
        b.lockInteger = 128;
        System.out.println("\n当128自动装箱Integer时");
        new Thread(new MyThreadInteger(a)).start();
        new Thread(new MyThreadInteger(b)).start();

        Thread.sleep(10000);
        a.lockInteger = new Integer(127);
        b.lockInteger = new Integer(127);
        System.out.println("\n当Integer堆时");
        new Thread(new MyThreadInteger(a)).start();
        new Thread(new MyThreadInteger(b)).start();

        Thread.sleep(10000);
        System.out.println("\n当String常量池装箱时");
        new Thread(new MyThreadString(a)).start();
        new Thread(new MyThreadString(b)).start();

        Thread.sleep(10000);
        System.out.println("\n当String堆时");
        new Thread(new MyThreadStringNew(a)).start();
        new Thread(new MyThreadStringNew(b)).start();

    }

    public void testIntegerLock() {
        System.out.println("testIntegerLock" + System.identityHashCode(lockInteger));
        synchronized (lockInteger) {
            try {
                System.out.println("starttestIntegerLock" + new Date());
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void testStringLock() {
        System.out.println("testStringLock" + System.identityHashCode(lockString));
        synchronized (lockString) {
            try {
                System.out.println("starttestStringLock"+ new Date());
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void testStringNewLock() {
        System.out.println("testStringNewLock" + System.identityHashCode(lockStringNew));
        synchronized (lockStringNew) {
            try {
                System.out.println("starttestStringNewLock"+ new Date());
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static class MyThreadInteger implements Runnable {

        private MultiLock multiLock;
        public MyThreadInteger(MultiLock multiLock) {
            this.multiLock = multiLock;
        }

        @Override
        public void run() {
            this.multiLock.testIntegerLock();
        }
    }

    public static class MyThreadString implements Runnable {

        private MultiLock multiLock;
        public MyThreadString(MultiLock multiLock) {
            this.multiLock = multiLock;
        }

        @Override
        public void run() {
            this.multiLock.testStringLock();
        }
    }

    public static class MyThreadStringNew implements Runnable {

        private MultiLock multiLock;
        public MyThreadStringNew(MultiLock multiLock) {
            this.multiLock = multiLock;
        }

        @Override
        public void run() {
            this.multiLock.testStringNewLock();
        }
    }
}
